package io.kiki.sba.registry.server.clientInterface.bootstrap;

import io.kiki.sba.registry.api.exchange.DataExchanger;
import io.kiki.sba.registry.api.exchange.NodeExchanger;
import io.kiki.sba.registry.common.model.slot.filter.SyncSlotAcceptAllManager;
import io.kiki.sba.registry.common.model.slot.filter.SyncSlotAcceptorManager;
import io.kiki.sba.registry.common.model.wrapper.WrapperInterceptor;
import io.kiki.sba.registry.remoting.http.exchange.HttpExchanger;
import io.kiki.sba.registry.remoting.netty.NettyDataExchanger;
import io.kiki.sba.registry.server.clientInterface.acceptor.WriteDataAcceptor;
import io.kiki.sba.registry.server.clientInterface.acceptor.WriteDataAcceptorImpl;
import io.kiki.sba.registry.server.clientInterface.cache.CacheGenerator;
import io.kiki.sba.registry.server.clientInterface.cache.CacheService;
import io.kiki.sba.registry.server.clientInterface.cache.DatumCacheGenerator;
import io.kiki.sba.registry.server.clientInterface.cache.SessionDatumCacheService;
import io.kiki.sba.registry.server.clientInterface.circuit.breaker.CircuitBreakerService;
import io.kiki.sba.registry.server.clientInterface.circuit.breaker.DefaultCircuitBreakerService;
import io.kiki.sba.registry.server.clientInterface.client.manager.CheckClientManagerService;
import io.kiki.sba.registry.server.clientInterface.connections.ConnectionsService;
import io.kiki.sba.registry.server.clientInterface.filter.IPMatchStrategy;
import io.kiki.sba.registry.server.clientInterface.filter.ProcessFilter;
import io.kiki.sba.registry.server.clientInterface.filter.blacklist.BlacklistMatchProcessFilter;
import io.kiki.sba.registry.server.clientInterface.filter.blacklist.DefaultIPMatchStrategy;
import io.kiki.sba.registry.server.clientInterface.limit.AccessLimitService;
import io.kiki.sba.registry.server.clientInterface.limit.AccessLimitServiceImpl;
import io.kiki.sba.registry.server.clientInterface.mapper.ConnectionMapper;
import io.kiki.sba.registry.server.clientInterface.metadata.MetadataCacheRegistry;
import io.kiki.sba.registry.server.clientInterface.multi.cluster.DataCenterCache;
import io.kiki.sba.registry.server.clientInterface.multi.cluster.DataCenterCacheImpl;
import io.kiki.sba.registry.server.clientInterface.node.service.*;
import io.kiki.sba.registry.server.clientInterface.providedata.*;
import io.kiki.sba.registry.server.clientInterface.push.*;
import io.kiki.sba.registry.server.clientInterface.registry.ClientInterfaceRegistry;
import io.kiki.sba.registry.server.clientInterface.registry.Registry;
import io.kiki.sba.registry.server.clientInterface.registry.RegistryScanCallable;
import io.kiki.sba.registry.server.clientInterface.remoting.ClientNodeExchanger;
import io.kiki.sba.registry.server.clientInterface.remoting.DataNodeExchanger;
import io.kiki.sba.registry.server.clientInterface.remoting.DataNodeNotifyExchanger;
import io.kiki.sba.registry.server.clientInterface.remoting.console.SessionConsoleExchanger;
import io.kiki.sba.registry.server.clientInterface.remoting.console.handler.*;
import io.kiki.sba.registry.server.clientInterface.remoting.handler.*;
import io.kiki.sba.registry.server.clientInterface.resource.*;
import io.kiki.sba.registry.server.clientInterface.scheduler.timertask.CacheCountTask;
import io.kiki.sba.registry.server.clientInterface.scheduler.timertask.SessionCacheDigestTask;
import io.kiki.sba.registry.server.clientInterface.scheduler.timertask.SyncClientsHeartbeatTask;
import io.kiki.sba.registry.server.clientInterface.slot.SlotsCache;
import io.kiki.sba.registry.server.clientInterface.slot.SlotsCacheImpl;
import io.kiki.sba.registry.server.clientInterface.store.*;
import io.kiki.sba.registry.server.clientInterface.strategy.*;
import io.kiki.sba.registry.server.clientInterface.strategy.impl.*;
import io.kiki.sba.registry.server.clientInterface.wrapper.*;
import io.kiki.sba.registry.server.shared.client.manager.BaseClientManagerService;
import io.kiki.sba.registry.server.shared.client.manager.ClientManagerService;
import io.kiki.sba.registry.server.shared.config.CommonConfig;
import io.kiki.sba.registry.server.shared.meta.CentralControlLeaderExchanger;
import io.kiki.sba.registry.server.shared.meta.MetaServerService;
import io.kiki.sba.registry.server.shared.providedata.FetchSystemPropertyService;
import io.kiki.sba.registry.server.shared.providedata.ProvideDataProcessor;
import io.kiki.sba.registry.server.shared.providedata.SystemPropertyProcessorManager;
import io.kiki.sba.registry.server.shared.remoting.AbstractClientHandler;
import io.kiki.sba.registry.server.shared.remoting.AbstractServerHandler;
import io.kiki.sba.registry.server.shared.remoting.SlotsChangeEventHandler;
import io.kiki.sba.registry.server.shared.resource.MetricsResource;
import io.kiki.sba.registry.server.shared.resource.RegistryOpsResource;
import io.kiki.sba.registry.server.shared.resource.SlotGenericResource;
import io.kiki.sba.registry.server.shared.resource.VersionResource;
import io.kiki.sba.registry.server.shared.slot.DiskSlotsRecorder;
import io.kiki.sba.registry.store.api.config.StoreApiConfiguration;
import io.kiki.sba.registry.store.jdbc.config.JdbcConfiguration;
import io.kiki.sba.registry.task.MetricsableThreadPoolExecutor;
import io.kiki.sba.registry.util.NamedThreadFactory;
import io.kiki.sba.registry.util.PropertySplitter;
import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


@Configuration
@Import({SessionServerInitializer.class, StoreApiConfiguration.class, JdbcConfiguration.class})
@EnableConfigurationProperties
public class ServerConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public Bootstrap sessionServerBootstrap() {
        return new Bootstrap();
    }

    @Configuration
    public static class SessionServerConfigBeanConfiguration {
        @Bean
        public CommonConfig commonConfig() {
            return new CommonConfig();
        }

        @Bean
        @ConditionalOnMissingBean
        public Config sessionServerConfig(CommonConfig commonConfig) {
            return new ConfigBean(commonConfig);
        }

        @Bean(name = "PropertySplitter")
        public PropertySplitter propertySplitter() {
            return new PropertySplitter();
        }

        @Bean
        public DiskSlotsRecorder diskSlotsRecorder() {
            return new DiskSlotsRecorder();
        }
    }

    @Configuration
    public static class SessionRemotingConfiguration {

        @Bean
        @ConditionalOnMissingBean(name = "boltExchange")
        public DataExchanger boltExchange() {
            return new NettyDataExchanger();
        }

        @Bean
        public DataExchanger jerseyExchange() {
            return new HttpExchanger();
        }

        @Bean
        public NodeExchanger clientNodeExchanger() {
            return new ClientNodeExchanger();
        }

        @Bean
        public NodeExchanger sessionConsoleExchanger() {
            return new SessionConsoleExchanger();
        }

        @Bean
        public DataNodeExchanger dataNodeExchanger() {
            return new DataNodeExchanger();
        }

        @Bean
        public DataNodeNotifyExchanger dataNodeNotifyExchanger() {
            return new DataNodeNotifyExchanger();
        }

        @Bean
        public CentralControlLeaderExchanger metaLeaderExchanger() {
            return new SessionCentralControlServerManager();
        }

        @Bean
        public SlotsCache SlotsCache() {
            return new SlotsCacheImpl();
        }

        @Bean
        public DataCenterCache dataCenterMetadataCache() {
            return new DataCenterCacheImpl();
        }

        @Bean(name = "serverHandlers")
        public Collection<AbstractServerHandler> serverHandlers() {
            Collection<AbstractServerHandler> list = new ArrayList<>();
            list.add(publisherHandler());
            list.add(subscriberHandler());
            list.add(watcherHandler());
            list.add(clientNodeConnectionHandler());
            list.add(syncConfigHandler());
            list.add(publisherPbHandler());
            list.add(subscriberPbHandler());
            list.add(syncConfigPbHandler());
            list.add(metadataRegisterPbHandler());
            list.add(serviceAppMappingHandler());
            list.add(metaRevisionHeartbeatHandler());
            list.add(getRevisionHandler());

            return list;
        }

        @Bean(name = "sessionSyncHandlers")
        public Collection<AbstractServerHandler> serverSyncHandlers() {
            Collection<AbstractServerHandler> list = new ArrayList<>();
            list.add(dataSlotDiffDigestRequestHandler());
            list.add(dataSlotDiffPublisherRequestHandler());
            return list;
        }

        @Bean(name = "consoleHandlers")
        public Collection<AbstractServerHandler> consoleHandlers() {
            Collection<AbstractServerHandler> list = new ArrayList<>();
            list.add(querySubscriberRequestHandler());
            list.add(clientOffRequestHandler());
            list.add(clientOnRequestHandler());
            list.add(getClientManagerRequestHandler());
            list.add(checkClientManagerHandler());
            list.add(pubSubDataInfoIdRequestHandler());
            list.add(filterSubscriberIPsHandler());
            list.add(stopPushRequestHandler());
            return list;
        }

        @Bean
        public AbstractServerHandler publisherHandler() {
            return new PublisherHandler();
        }

        @Bean
        public AbstractServerHandler syncConfigHandler() {
            return new SyncConfigHandler();
        }

        @Bean
        public AbstractServerHandler subscriberHandler() {
            return new SubscriberHandler();
        }

        @Bean
        public AbstractServerHandler watcherHandler() {
            return new WatcherHandler();
        }

        @Bean
        public AbstractServerHandler clientNodeConnectionHandler() {
            return new ClientNodeConnectionHandler();
        }

        @Bean
        public AbstractServerHandler querySubscriberRequestHandler() {
            return new QuerySubscriberRequestHandler();
        }

        @Bean
        public AbstractServerHandler filterSubscriberIPsHandler() {
            return new FilterSubscriberIPsHandler();
        }

        @Bean
        public AbstractServerHandler clientOffRequestHandler() {
            return new ClientOffRequestHandler();
        }

        @Bean
        public AbstractServerHandler clientOnRequestHandler() {
            return new ClientOnRequestHandler();
        }

        @Bean
        public AbstractServerHandler getClientManagerRequestHandler() {
            return new GetClientManagerRequestHandler();
        }

        @Bean
        public AbstractServerHandler checkClientManagerHandler() {
            return new CheckClientManagerHandler();
        }

        @Bean
        public AbstractServerHandler stopPushRequestHandler() {
            return new StopPushRequestHandler();
        }

        @Bean
        public AbstractServerHandler pubSubDataInfoIdRequestHandler() {
            return new PubSubDataInfoIdRequestHandler();
        }

        @Bean
        public AbstractServerHandler dataSlotDiffDigestRequestHandler() {
            return new DataSlotDiffDigestRequestHandler();
        }

        @Bean
        public SyncSlotAcceptorManager syncSlotAcceptAllManager() {
            return new SyncSlotAcceptAllManager();
        }

        @Bean
        public AbstractServerHandler dataSlotDiffPublisherRequestHandler() {
            return new DataSlotDiffPublisherRequestHandler();
        }

        @Bean
        public AbstractServerHandler publisherPbHandler() {
            return new PublisherPbHandler();
        }

        @Bean
        public AbstractServerHandler metadataRegisterPbHandler() {
            return new MetadataRegisterPbHandler();
        }

        @Bean
        public AbstractServerHandler serviceAppMappingHandler() {
            return new ServiceAppMappingPbHandler();
        }

        @Bean
        public AbstractServerHandler getRevisionHandler() {
            return new GetRevisionPbHandler();
        }

        @Bean
        public AbstractServerHandler metaRevisionHeartbeatHandler() {
            return new MetaRevisionHeartbeatPbHandler();
        }

        @Bean
        public AbstractServerHandler subscriberPbHandler() {
            return new SubscriberPbHandler();
        }

        @Bean
        public AbstractServerHandler syncConfigPbHandler() {
            return new SyncConfigPbHandler();
        }

        @Bean
        @ConditionalOnMissingBean(name = "circuitBreakerService")
        public CircuitBreakerService circuitBreakerService() {
            return new DefaultCircuitBreakerService();
        }

        @Bean(name = "dataNotifyClientHandlers")
        public Collection<AbstractClientHandler> dataClientHandlers() {
            Collection<AbstractClientHandler> list = new ArrayList<>();
            list.add(dataChangeRequestHandler());
            list.add(dataPushRequestHandler());
            return list;
        }

        @Bean(name = "metaClientHandlers")
        public Collection<AbstractClientHandler> metaClientHandlers() {
            Collection<AbstractClientHandler> list = new ArrayList<>();
            list.add(notifyProvideDataChangeHandler());
            list.add(SlotsChangeEventHandler());
            list.add(appRevisionSliceHandler());
            return list;
        }

        @Bean
        public AbstractClientHandler dataChangeRequestHandler() {
            return new DataChangeRequestHandler();
        }

        @Bean
        public AbstractClientHandler dataPushRequestHandler() {
            return new DataPushRequestHandler();
        }

        @Bean
        public AbstractClientHandler notifyProvideDataChangeHandler() {
            return new NotifyProvideDataChangeHandler();
        }

        @Bean
        public AbstractClientHandler appRevisionSliceHandler() {
            return new AppRevisionSliceHandler();
        }

        @Bean
        public SlotsChangeEventHandler SlotsChangeEventHandler() {
            return new SlotsChangeEventHandler();
        }
    }

    @Configuration
    public static class ResourceConfiguration {

        @Bean
        public ResourceConfig jerseyResourceConfig() {
            ResourceConfig resourceConfig = new ResourceConfig();
            resourceConfig.register(JacksonFeature.class);
            return resourceConfig;
        }

        @Bean
        @ConditionalOnMissingBean(name = "sessionOpenResource")
        public SessionOpenResource sessionOpenResource() {
            return new SessionOpenResource();
        }

        @Bean
        public SessionDigestResource sessionDigestResource() {
            return new SessionDigestResource();
        }

        @Bean
        @ConditionalOnMissingBean(name = "healthResource")
        public HealthResource healthResource() {
            return new HealthResource();
        }

        @Bean
        public CompressResource compressResource() {
            return new CompressResource();
        }

        @Bean
        public ClientsOpenResource clientsOpenResource() {
            return new ClientsOpenResource();
        }

        @Bean
        public ConnectionsResource connectionsResource() {
            return new ConnectionsResource();
        }

        @Bean
        public SlotGenericResource slotGenericResource() {
            return new SlotGenericResource();
        }

        @Bean
        public MetricsResource metricsResource() {
            return new MetricsResource();
        }

        @Bean
        @ConditionalOnMissingBean
        public VersionResource versionResource() {
            return new VersionResource();
        }

        @Bean
        public RegistryOpsResource opsResource() {
            return new RegistryOpsResource();
        }

        @Bean
        public ClientManagerResource clientManagerResource() {
            return new ClientManagerResource();
        }

        @Bean
        public PersistenceClientManagerResource persistenceClientManagerResource() {
            return new PersistenceClientManagerResource();
        }

        @Bean
        public SlotsStatusResource SlotsStatusResource() {
            return new SlotsStatusResource();
        }

        @Bean
        public MetadataCacheResource metadataCacheResource() {
            return new MetadataCacheResource();
        }

        @Bean
        public EmergencyApiResource emergencyApiResource() {
            return new EmergencyApiResource();
        }
    }

    @Configuration
    public static class SessionRegistryConfiguration {
        @Bean
        @ConditionalOnMissingBean(name = "sessionRegistry")
        public Registry sessionRegistry() {
            return new ClientInterfaceRegistry();
        }

        @Bean
        @ConditionalOnMissingBean
        public Subscribers interests() {
            return new SubscribersImpl();
        }

        @Bean
        @ConditionalOnMissingBean
        public Watchers sessionWatchers() {
            return new WatchersImpl();
        }

        @Bean
        @ConditionalOnMissingBean
        public Publishers dataStore() {
            return new PublishersImpl();
        }

        @Bean
        public RegistryScanCallable registryScanCallable() {
            return new RegistryScanCallable();
        }
    }

    @Configuration
    public static class SessionNodeConfiguration {

        @Bean
        @ConditionalOnMissingBean
        public DataStoreNodeService dataNodeService() {
            return new DataStoreNodeServiceImpl();
        }

        @Bean
        @ConditionalOnMissingBean
        public MetaServerService metaServerService() {
            return new MetaServerServiceImpl();
        }

        @Bean
        @ConditionalOnMissingBean
        public ClientNodeService clientNodeService() {
            return new ClientNodeServiceImpl();
        }

        @Bean
        @ConditionalOnMissingBean
        public FirePushService firePushService(Config config) {
            return new FirePushService(config);
        }

        @Bean
        @ConditionalOnMissingBean
        public PushProcessor pushProcessor() {
            return new PushProcessor();
        }

        @Bean
        @ConditionalOnMissingBean
        public WatchProcessor watchProcessor() {
            return new WatchProcessor();
        }

        @Bean
        @ConditionalOnMissingBean
        public ChangeProcessor changeProcessor() {
            return new ChangeProcessor();
        }

        @Bean
        @ConditionalOnMissingBean
        public PushDataGenerator pushDataGenerator() {
            return new PushDataGenerator();
        }

        @Bean
        public PushSwitchService pushSwitchService() {
            return new PushSwitchService();
        }

        @Bean
        @ConditionalOnMissingBean
        public FetchPubSubDataInfoIdService fetchPubSubDataInfoIdService() {
            return new FetchPubSubDataInfoIdService();
        }

        @Bean
        public ClientManagerService clientManagerService() {
            return new BaseClientManagerService();
        }

        @Bean
        public CheckClientManagerService checkClientManagerService() {
            return new CheckClientManagerService();
        }
    }

    @Configuration
    public static class SessionCacheConfiguration {

        @Bean
        public CacheService sessionDatumCacheService() {
            return new SessionDatumCacheService();
        }

        @Bean(name = "com.alipay.sofa.registry.server.session.cache.DatumKey")
        public CacheGenerator datumCacheGenerator() {
            return new DatumCacheGenerator();
        }

        @Bean
        public MetadataCacheRegistry metadataCacheRegistry() {
            return new MetadataCacheRegistry();
        }
    }

    @Configuration
    public static class ExecutorConfiguration {

        @Bean(name = "metaNodeExecutor")
        public ThreadPoolExecutor metaNodeExecutor(Config config) {
            return new MetricsableThreadPoolExecutor("metaNodeInSessionExecutor", config.getMetaNodeWorkerSize(), config.getMetaNodeWorkerSize(), 300, TimeUnit.SECONDS, new ArrayBlockingQueue<>(config.getMetaNodeBufferSize()), new NamedThreadFactory("metaNodeInSessionExecutor", true));
        }

        @Bean
        public ExecutorManager executorManager(Config config) {
            return new ExecutorManager(config);
        }
    }

    @Configuration
    public static class SessionTimerTaskConfiguration {

        @Bean
        public SyncClientsHeartbeatTask syncClientsHeartbeatTask() {
            return new SyncClientsHeartbeatTask();
        }

        @Bean
        public SessionCacheDigestTask sessionCacheDigestTask() {
            return new SessionCacheDigestTask();
        }

        @Bean
        public CacheCountTask cacheCountTask() {
            return new CacheCountTask();
        }
    }

    @Configuration
    public static class SessionStrategyConfiguration {
        @Bean
        @ConditionalOnMissingBean
        public RegistryStrategy sessionRegistryStrategy() {
            return new DefaultRegistryStrategy();
        }

        @Bean
        @ConditionalOnMissingBean
        public SyncConfigHandlerStrategy syncConfigHandlerStrategy() {
            return new DefaultSyncConfigHandlerStrategy();
        }

        @Bean
        @ConditionalOnMissingBean
        public PublisherHandlerStrategy publisherHandlerStrategy() {
            return new DefaultPublisherHandlerStrategy();
        }

        @Bean
        @ConditionalOnMissingBean
        public SubscriberHandlerStrategy subscriberHandlerStrategy() {
            return new DefaultSubscriberHandlerStrategy();
        }

        @Bean
        @ConditionalOnMissingBean
        public WatcherHandlerStrategy watcherHandlerStrategy() {
            return new DefaultWatcherHandlerStrategy();
        }

        @Bean
        @ConditionalOnMissingBean
        public AppRevisionHandlerStrategy appRevisionHandlerStrategy() {
            return new DefaultAppRevisionHandlerStrategy();
        }
    }

    @Configuration
    public static class AccessLimitServiceConfiguration {
        @Bean
        public AccessLimitService accessLimitService(Config config) {
            return new AccessLimitServiceImpl(config);
        }
    }

    @Configuration
    public static class SessionFilterConfiguration {

        @Bean
        public IPMatchStrategy ipMatchStrategy() {
            return new DefaultIPMatchStrategy();
        }

        @Bean
        @ConditionalOnMissingBean
        public ProcessFilter blacklistMatchProcessFilter() {
            return new BlacklistMatchProcessFilter();
        }

        @Bean
        public WrapperInterceptorManager wrapperInterceptorManager() {
            WrapperInterceptorManager wrapperInterceptorManager = new WrapperInterceptorManager();
            wrapperInterceptorManager.addInterceptor(clientCheckWrapperInterceptor());
            wrapperInterceptorManager.addInterceptor(blacklistWrapperInterceptor());
            wrapperInterceptorManager.addInterceptor(accessLimitWrapperInterceptor());
            wrapperInterceptorManager.addInterceptor(clientOffWrapperInterceptor());
            return wrapperInterceptorManager;
        }

        @Bean
        public WrapperInterceptor clientCheckWrapperInterceptor() {
            return new ClientCheckWrapperInterceptor();
        }

        @Bean
        public WrapperInterceptor blacklistWrapperInterceptor() {
            return new BlacklistWrapperInterceptor();
        }

        @Bean
        public WrapperInterceptor clientOffWrapperInterceptor() {
            return new ClientOffWrapperInterceptor();
        }

        @Bean
        public WrapperInterceptor accessLimitWrapperInterceptor() {
            return new AccessLimitWrapperInterceptor();
        }
    }

    @Configuration
    public static class SessionRenewDatumConfiguration {

        @Bean
        public WriteDataAcceptor writeDataAcceptor() {
            return new WriteDataAcceptorImpl();
        }
    }

    @Configuration
    public static class SessionConnectionsConfiguration {
        @Bean
        public ConnectionsService connectionsService() {
            return new ConnectionsService();
        }

        @Bean
        public ConnectionMapper connectionMapper() {
            return new ConnectionMapper();
        }
    }

    @Configuration
    public static class SessionProvideDataConfiguration {

        @Bean
        public SystemPropertyProcessorManager systemPropertyProcessorManager() {
            return new SystemPropertyProcessorManager();
        }

        @Bean
        public ProvideDataProcessor provideDataProcessorManager() {
            return new ProvideDataProcessorManager();
        }

        @Bean
        public FetchSystemPropertyService fetchBlackListService(SystemPropertyProcessorManager systemPropertyProcessorManager) {
            FetchBlackListService fetchBlackListService = new FetchBlackListService();
            systemPropertyProcessorManager.addSystemDataProcessor(fetchBlackListService);
            return fetchBlackListService;
        }

        @Bean
        public FetchSystemPropertyService fetchStopPushService(SystemPropertyProcessorManager systemPropertyProcessorManager) {
            FetchStopPushService fetchStopPushService = new FetchStopPushService();
            systemPropertyProcessorManager.addSystemDataPersistenceProcessor(fetchStopPushService);

            return fetchStopPushService;
        }

        @Bean
        public FetchSystemPropertyService fetchClientOffAddressService(SystemPropertyProcessorManager systemPropertyProcessorManager) {
            FetchClientOffAddressService fetchClientOffAddressService = new FetchClientOffAddressService();
            systemPropertyProcessorManager.addSystemDataPersistenceProcessor(fetchClientOffAddressService);

            return fetchClientOffAddressService;
        }

        @Bean
        public FetchSystemPropertyService fetchGrayPushSwitchService(SystemPropertyProcessorManager systemPropertyProcessorManager) {
            FetchGrayPushSwitchService fetchGrayPushSwitchService = new FetchGrayPushSwitchService();
            systemPropertyProcessorManager.addSystemDataProcessor(fetchGrayPushSwitchService);

            return fetchGrayPushSwitchService;
        }

        @Bean
        public FetchSystemPropertyService compressPushService(SystemPropertyProcessorManager systemPropertyProcessorManager) {
            CompressPushService compressPushService = new CompressPushService();
            systemPropertyProcessorManager.addSystemDataProcessor(compressPushService);
            return compressPushService;
        }

        @Bean
        public FetchSystemPropertyService appRevisionWriteSwitchService(SystemPropertyProcessorManager systemPropertyProcessorManager) {
            AppRevisionWriteSwitchService appRevisionWriteSwitchService = new AppRevisionWriteSwitchService();
            systemPropertyProcessorManager.addSystemDataProcessor(appRevisionWriteSwitchService);
            return appRevisionWriteSwitchService;
        }

        @Bean
        public FetchSystemPropertyService changeTaskWorkDelayService(SystemPropertyProcessorManager systemPropertyProcessorManager) {
            FetchPushEfficiencyConfigService fetchPushEfficiencyConfigService = new FetchPushEfficiencyConfigService();
            systemPropertyProcessorManager.addSystemDataProcessor(fetchPushEfficiencyConfigService);
            return fetchPushEfficiencyConfigService;
        }

        @Bean
        public FetchSystemPropertyService fetchShutdownService(SystemPropertyProcessorManager systemPropertyProcessorManager) {
            FetchShutdownService fetchShutdownService = new FetchShutdownService();
            systemPropertyProcessorManager.addSystemDataPersistenceProcessor(fetchShutdownService);

            return fetchShutdownService;
        }

        @Bean
        public FetchCircuitBreakerService fetchCircuitBreakerService(SystemPropertyProcessorManager systemPropertyProcessorManager) {
            FetchCircuitBreakerService fetchCircuitBreakerService = new FetchCircuitBreakerService();
            systemPropertyProcessorManager.addSystemDataPersistenceProcessor(fetchCircuitBreakerService);
            return fetchCircuitBreakerService;
        }

        @Bean
        public ConfigProvideDataWatcher configProvideDataWatcher() {
            return new ConfigProvideDataWatcher();
        }
    }
}
